/**
 * @class Legend
 * @constructor
 */

var Legend = Class.create( {

    initialize: function(title, allowDrop) {
        this._affectedNodes  = {};     

        this._objectColors = {};       

        var legendContainer = $('legend-container');
        if (legendContainer == undefined) {
            var legendContainer = new Element('div', {'class': 'legend-container', 'id': 'legend-container'});
            editor.getWorkspace().getWorkArea().insert(legendContainer);
        }

        this._legendBox = new Element('div', {'class' : 'legend-box', id: 'legend-box'});
        this._legendBox.hide();
        legendContainer.insert(this._legendBox);
      var legendTitle= new Element('h2', {'class' : 'legend-title'}).update(title);
      this._legendBox.insert(legendTitle);

      this._list = new Element('ul', {'class' : 'disorder-list'});
      this._legendBox.insert(this._list);
        Element.observe(this._legendBox, 'mouseover', function() {
            $$('.menu-box').invoke('setOpacity', .1);
        });
        Element.observe(this._legendBox, 'mouseout', function() {
            $$('.menu-box').invoke('setOpacity', 1);
        });

        if (allowDrop) {
            Droppables.add(editor.getWorkspace().canvas, {accept: 'drop-'+this._getPrefix(), onDrop: this._onDropWrapper.bind(this)});
        }
    },

    /**
     *
     * @method _getPrefix
     * @param {String|Number} id 
     * @return {String} some identifier 
     */
    _getPrefix: function(id) {
        throw "prefix not defined";
    },

    /**
     *
     * @method getObjectColor
     * @param {String|Number} id 
     * @return {String} CSS color 
     */
      
    _isQuadrantFirst: function(firstCancerName) {
        return (
        	firstCancerName == '甲状腺癌' || 
        	firstCancerName == '肺癌'|| 
        	firstCancerName == '脑瘤'|| 
        	firstCancerName == '神经胶质瘤'|| 
        	firstCancerName == '白血病'|| 
        	firstCancerName == '霍奇金淋巴瘤'|| 
        	firstCancerName == '非霍奇金淋巴瘤'|| 
        	firstCancerName == '黑色素瘤'|| 
        	firstCancerName == '皮肤癌'|| 
        	firstCancerName == '鼻咽癌'|| 
        	firstCancerName == '喉头癌'|| 
        	firstCancerName == '舌癌'|| 
        	firstCancerName == '骨癌'|| 
        	firstCancerName == '原发性腹膜癌'|| 
        	firstCancerName == '儿童肉瘤' ||
        	firstCancerName == '骨肉瘤' ||
        	firstCancerName == '软组织肉瘤' ||
        	firstCancerName == '神经节瘤' ||
        	firstCancerName == '副神经节瘤' ||
        	firstCancerName == '嗜铬细胞瘤' ||
        	firstCancerName == '心脏横纹肌瘤' ||
        	firstCancerName == '横纹肌肉瘤' ||
        	firstCancerName == '脉络丛癌' ||
        	firstCancerName == '砂粒性黑色素神经鞘瘤' ||
        	firstCancerName == '淋巴管肌瘤病' ||
        	firstCancerName == '内淋巴囊肿瘤' ||
        	firstCancerName == '巨细胞星形细胞瘤' ||
        	firstCancerName == '皮肤和黏膜粘液瘤' ||
        	firstCancerName == '心肌粘液瘤' ||
        	firstCancerName == '乳腺粘液瘤' ||
        	firstCancerName == '骨软骨粘液瘤' ||
        	firstCancerName == '神经纤维瘤' ||
        	firstCancerName == '丛状神经纤维瘤' ||
        	firstCancerName == '面部血管纤维瘤' ||
        	firstCancerName == '甲周纤维瘤' ||
        	firstCancerName == '牙龈纤维瘤' ||
        	firstCancerName == '视网膜结节状错构瘤' ||
        	firstCancerName == '视网膜毛细血管瘤' ||
        	firstCancerName == '视网膜母细胞瘤' ||
        	firstCancerName == '恶性胶质瘤' ||
        	firstCancerName == '视神经胶质瘤' ||
        	firstCancerName == '毛鞘瘤' ||
        	firstCancerName == '皮肤黏膜神经瘤' ||
        	firstCancerName == '眼部神经瘤' ||
        	firstCancerName == '口腔神经瘤' ||
        	firstCancerName == '口腔乳头瘤' ||
        	firstCancerName == '皮脂腺瘤' ||
        	firstCancerName == '角化棘皮瘤' ||
        	firstCancerName == '细支气管肺泡癌' ||
        	firstCancerName == '硬纤维瘤' ||
        	firstCancerName == '脂肪瘤' ||
        	firstCancerName == '甲状腺腺瘤' ||
        	firstCancerName == '乳腺导管腺瘤' ||
        	firstCancerName == '中枢神经系统血管膜细胞瘤' ||
            firstCancerName == '肝母细胞瘤'
        
        )
    },
    _isQuadrantSecond: function(secondCancerName) {
        return (secondCancerName == '乳腺癌')
    },
    _isQuadrantThird: function(thirdCancerName) {
        return (thirdCancerName == '卵巢癌' || thirdCancerName == '子宫内膜癌'
            || thirdCancerName == '前列腺癌' || thirdCancerName == '肾癌' || 
            thirdCancerName == '卵巢纤维肉瘤'  ||
            thirdCancerName == '卵巢伴环状小管性索瘤'  ||
            thirdCancerName == '高钙血型小细胞卵巢癌'  ||
            thirdCancerName == '输卵管癌'  ||
            thirdCancerName == '肾上腺皮质癌'  ||
            thirdCancerName == '肾血管平滑肌脂肪瘤'  ||
            thirdCancerName == '膀胱癌'  ||
            thirdCancerName == '胆管癌'  ||
            thirdCancerName == '输尿管癌'  ||
            thirdCancerName == '肾盂肾癌'  ||
            thirdCancerName == '尿路癌'  ||
            thirdCancerName == '睾丸癌'  ||
            thirdCancerName == '睾丸支持细胞瘤'  ||
            thirdCancerName == '睾丸大细胞钙化型支持细胞瘤'  ||
            thirdCancerName == '宫颈癌'  ||
            thirdCancerName == '宫颈恶性腺瘤'
        )
    },
    _isQuadrantFour: function(fourCancerName) {
        return (fourCancerName == '结直肠癌' || fourCancerName == '胃癌'
            || fourCancerName == '胰腺癌' || 
            fourCancerName == '胃肠间质瘤' || 
            fourCancerName == '胃肠道错构瘤' || 
            fourCancerName == '胃肠道弥漫性神经节瘤病' || 
            fourCancerName == '食管癌' || 
            fourCancerName == '肝癌' || 
            fourCancerName == '胆囊癌' || 
            fourCancerName == '小肠癌'
        )
    },
    //3399CC  FF99CC FFCC66 99CC33
    getObjectColor: function(id) {
        if(this._isQuadrantFirst(id)) {
        		return "#3399CC";
        } 
        if(this._isQuadrantSecond(id)) {
        		return "#FF99CC";
        }
        
        if(this._isQuadrantThird(id)) {
        		return "#FFCC66";
        } 
        if(this._isQuadrantFour(id)) {
        		return "#99CC33";
        } 
        if (!this._objectColors.hasOwnProperty(id))
            return "black";
        return this._objectColors[id];
    },

    /**
     *
     * @method _hasAffectedNodes
     * @param {String|Number} id ID of the object
     * @private
     */
    _hasAffectedNodes: function(id) {
        return this._affectedNodes.hasOwnProperty(id);
    },
    /**
     *
     * @method addCase
     * @param {String|Number} id 
     * @param {String} Name 
     * @param {Number} nodeID 
     */
    addCase: function(id, name, nodeID) {
        if(Object.keys(this._affectedNodes).length == 0) {
            this._legendBox.show();
        }
        if(!this._hasAffectedNodes(id)) {
            this._affectedNodes[id] = [nodeID];
            var listElement = this._generateElement(id, name);
            this._list.insert(listElement);
        }
        else {
            this._affectedNodes[id].push(nodeID);
        }
        this._updateCaseNumbersForObject(id);
    },
    /**
     *
     * @param {String|Number} id 
     * @param {Number} nodeID 
     */
    removeCase: function(id, nodeID) {
        if (this._hasAffectedNodes(id)) {
            this._affectedNodes[id] = this._affectedNodes[id].without(nodeID);
            if(this._affectedNodes[id].length == 0) {
                delete this._affectedNodes[id];
                delete this._objectColors[id];
                var htmlElement = this._getListElementForObjectWithID(id)
                htmlElement.remove();
                if(Object.keys(this._affectedNodes).length == 0) {
                    this._legendBox.hide();
                }
            }
            else {
                this._updateCaseNumbersForObject(id);
            }
        }
    },

    _getListElementForObjectWithID: function(id) {
        return $(this._getPrefix() + '-' + id);
    },

    /**
     *
     * @method _updateCaseNumbersForObject
     * @param {String|Number} id 
     * @private
     */
    _updateCaseNumbersForObject : function(id) {
      var label = this._legendBox.down('li#' + this._getPrefix() + '-' + id + ' .disorder-cases');
      if (label) {
        var cases = this._affectedNodes.hasOwnProperty(id) ? this._affectedNodes[id].length : 0;
        label.update(cases + "&nbsp;case" + ((cases - 1) && "s" || ""));
      }
    },

    /**
     * @method _generateElement
     * @param {String|Number} id 
     * @param {String} name 
     * @return {HTMLLIElement} 
     */
    _generateElement: function(id, name) {
        var color = this.getObjectColor(id);
        var item = new Element('li', {'class' : 'disorder '+'drop-'+this._getPrefix(), 'id' : this._getPrefix() + '-' + id}).update(new Element('span', {'class' : 'disorder-name'}).update(name));
        var bubble = new Element('span', {'class' : 'disorder-color'});
        bubble.style.backgroundColor = color;
        item.insert({'top' : bubble});
        var countLabel = new Element('span', {'class' : 'disorder-cases'});
        var countLabelContainer = new Element('span', {'class' : 'disorder-cases-container'}).insert("(").insert(countLabel).insert(")");
        item.insert(" ").insert(countLabelContainer);
        var me = this;
        Element.observe(item, 'mouseover', function() {
            item.down('.disorder-name').setStyle({'background': color, 'cursor' : 'default'});
            me._affectedNodes[id] && me._affectedNodes[id].forEach(function(nodeID) {
                var node = editor.getNode(nodeID);
                node && node.getGraphics().highlight();
            });
        });
        Element.observe(item, 'mouseout', function() {
            item.down('.disorder-name').setStyle({'background':'', 'cursor' : 'default'});
            me._affectedNodes[id] && me._affectedNodes[id].forEach(function(nodeID) {
                var node = editor.getNode(nodeID);
                node && node.getGraphics().unHighlight();
            });
        });
        new Draggable(item, {
            revert: true,
            reverteffect: function(segment) {
              segment.setStyle({
                height: '',
                left: '',
                position: '',
                top: '',
                zIndex: '',
                width: ''
              });
            },
            ghosting: true
          });
        return item;
    },

    /**
     *
     * @method _onDropWrapper
     * @param {HTMLElement} [label]
     * @param {HTMLElement} [target]
     * @param {Event} [event]
     * @private
     */
    _onDropWrapper: function(label, target, event) {
        if (editor.isReadOnlyMode()) {
            return;
        }
        var divPos = editor.getWorkspace().viewportToDiv(event.pointerX(), event.pointerY());
        var pos    = editor.getWorkspace().divToCanvas(divPos.x,divPos.y);
        var node   = editor.getView().getPersonNodeNear(pos.x, pos.y);
        if (node) {
            var id = label.id.substring( label.id.indexOf('-') + 1 );
            this._onDropObject(node, id);
        }
    },
    /**
     *
     * @method _onDropGeneric
     * @param {Person} Person node
     * @param {String|Number} id ID of the object
     */
    _onDropObject: function(node, objectID) {
        throw "drop functionality is not defined";
    }
});
